#include <iostream>
#include <vector>
#include <queue>
#include <tuple>
using namespace std;

class Solution {
    public:
	int swimInWater(vector<vector<int>> &grid)
	{
                int n = grid.size();
                vector<vector<int>> vis(n, vector<int>(n, 0));
                vector<vector<int>> dis(n, vector<int>(n, INT32_MAX));
                priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;

                vector<int> direct = { -1, 0, 1, 0, -1 };
                pq.emplace(grid[0][0], 0, 0);
                dis[0][0] = grid[0][0];
                while(!pq.empty()){
                        auto [w, row, col] = pq.top();
                        pq.pop();
                        if(vis[row][col]){
                                continue;
                        }
                        vis[row][col] = 1;

                        for(int i = 0; i < 4; i++){
                                int nrow = row + direct[i];
                                int ncol = col + direct[i + 1];
                                if(nrow >= 0 && nrow < n && ncol >= 0 && ncol < n && !vis[nrow][ncol]){
                                        int cost = max(w, grid[nrow][ncol]);
                                        if(cost < dis[nrow][ncol]){
                                                dis[nrow][ncol] = cost;
                                                pq.emplace(cost, nrow, ncol);
                                        }
                                }
                        }
                }
                return dis[n - 1][n - 1];
	}
};

int main()
{
	vector<vector<int>> grid = { { 0, 2 }, { 1, 3 } };
        cout<<Solution().swimInWater(grid)<<endl;
        return 0;
}